package cc.rengu.oltp.service.realize.impl;

import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.NonFinanceTxnMapper;
import cc.rengu.oltp.service.common.dao.PayOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.NonFinanceTxnMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.PayOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.NonFinanceTxn;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.SrcChannelInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.MonitorModelTypeEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.*;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.TransMonitorService;
import cc.rengu.oltp.service.realize.TxnInfoService;
import cc.rengu.oltp.utility.util.*;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSON;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 交易监控缓件实现类
 * Created by 王成 on 2020/2/12
 */
public class TransMonitorServiceImpl implements TransMonitorService {
    private final RgLogger rglog = RgLog.getLogger(this.getClass().getName());
    private static final String TRANS_MONITOR_PARAM = "TRANS_MONITOR_PARAM";  /* 交易监控参数 */
    private static final String MONITOR_EXPIRY_TIMES = "MONITOR_EXPIRY_TIMES"; /* 交易监控缓存时间参数KEY */
    private static final int MONITOR_EXPIRY_SECONDS = 300;  /* 监控数据缓存默认有效时长 */

    @Override
    public void publishTransMonitorInfo() {
        try {
            XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
            /* Step1：获取交易关键信息(基于交易流水表的信息) */
            TransMonitorInfo transMonitorInfo = new TransMonitorInfo();
            ConvertUtil.convertOutput(transMonitorInfo);
            TxnInfo txnInfo = (TxnInfo) xmlTreeUtil.getXmlTreeObjectValue(TreeNodeConstant.TXN_INFO,TxnInfo.class);
            if (null == txnInfo){
                TxnInfoService txnInfoService = new TxnInfoServiceImpl();
                txnInfo = txnInfoService.getCurrentTxnInfo();
            }
            rglog.debug("推送交易<{}-{}>交易监控信息到Redis缓存!",txnInfo.getTxnKey(),txnInfo.getSrcTxnAuthCfg().getTxnName());
            transMonitorInfo.setTxnName(txnInfo.getSrcTxnAuthCfg().getTxnName());
            transMonitorInfo.setBizProdCode(txnInfo.getSrcTxnAuthCfg().getBizProdCode());
            /* Step2.1：获取支付通道信息 */
            List<ChannelMonitorInfo> channelMonitorInfoList = new ArrayList<>();
            String txnRegisterFlag = txnInfo.getSrcTxnAuthCfg().getTxnRegisterFlag();
            txnRegisterFlag = StringUtil.isEmptyOrNull(txnRegisterFlag) ? txnInfo.getSrcTxnAuthCfg().getTxnNum() : txnRegisterFlag;
            if (txnRegisterFlag.startsWith(AppParamConstant.FINANCE_TXN_HEAD)) {
                PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
                List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(transMonitorInfo.getInstId(), transMonitorInfo.getSysSeqNum());
                if (null != payOrderInfoList && !payOrderInfoList.isEmpty()) {
                    payOrderInfoList.forEach(item -> {
                        ChannelMonitorInfo channelMonitorInfo = new ChannelMonitorInfo();
                        channelMonitorInfo.setChannelId(item.getMsgDstId());
                        channelMonitorInfo.setTransStatus(item.getTransStatus());
                        long channelTxnCost = DateUtil.getTimeCost(item.getCreateTime(), item.getUpdateTime());
                        channelMonitorInfo.setChannelTxnCost((int) channelTxnCost);
                        channelMonitorInfoList.add(channelMonitorInfo);
                    });
                }
            } else if (txnRegisterFlag.startsWith(AppParamConstant.NON_FINANCE_TXN_HEAD)){
                NonFinanceTxnMapper nonFinanceTxnMapper = new NonFinanceTxnMapperImpl();
                NonFinanceTxn nonFinanceTxn = nonFinanceTxnMapper.selectNonFinanceTxnInfoByPrimaryKey(transMonitorInfo.getInstId(), transMonitorInfo.getSysSeqNum());
                if (null != nonFinanceTxn) {
                    ChannelMonitorInfo channelMonitorInfo = new ChannelMonitorInfo();
                    channelMonitorInfo.setChannelId(StringUtil.isEmptyOrNull(nonFinanceTxn.getChannelId()) ? AppParamConstant.IGAS : nonFinanceTxn.getChannelId());
                    channelMonitorInfo.setTransStatus(nonFinanceTxn.getTxnStatus());
                    long channelTxnCost = DateUtil.getTimeCost(nonFinanceTxn.getCreateTime(), nonFinanceTxn.getUpdateTime());
                    channelMonitorInfo.setChannelTxnCost((int) channelTxnCost);
                    channelMonitorInfoList.add(channelMonitorInfo);
                }
            }
            transMonitorInfo.setChannelMonitorInfoList(channelMonitorInfoList);
            /* Step2.2： 获取交易渠道信息 */
            String srcChannelInfoKey = transMonitorInfo.getInstId().trim() + txnInfo.getSrcTxnAuthCfg().getMsgSrcId().trim() + transMonitorInfo.getTransChannelId().trim();
            SrcChannelInfo srcChannelInfo = JSON.parseObject(RedisUtil.hashGet(AppParamConstant.CHANNEL_ACQ_INFO_CACHE, srcChannelInfoKey), SrcChannelInfo.class);
            if (null == srcChannelInfo) {
                srcChannelInfoKey = transMonitorInfo.getInstId().trim() + txnInfo.getSrcTxnAuthCfg().getMsgSrcId().trim() + "*";
                srcChannelInfo = JSON.parseObject(RedisUtil.hashGet(AppParamConstant.CHANNEL_ACQ_INFO_CACHE, srcChannelInfoKey), SrcChannelInfo.class);
                if (null != srcChannelInfo) {
                    transMonitorInfo.setSrcChannelId(srcChannelInfo.getSrcChannelId());
                    transMonitorInfo.setSrcChannelName(srcChannelInfo.getSrcChannelName());
                    transMonitorInfo.setTransChannelName(srcChannelInfo.getTransChannelName());
                }
            } else {
                transMonitorInfo.setSrcChannelId(srcChannelInfo.getSrcChannelId());
                transMonitorInfo.setSrcChannelName(srcChannelInfo.getSrcChannelName());
                transMonitorInfo.setTransChannelName(srcChannelInfo.getTransChannelName());
            }
            /* Step2.3：若交易日期及交易时间为空，则设置当前系统日期及时间 */
            if (StringUtil.isEmptyOrNull(transMonitorInfo.getTxnDate())) {
                transMonitorInfo.setTxnDate(DateUtil.getCurrentDate());
            }
            if (StringUtil.isEmptyOrNull(transMonitorInfo.getTxnTime())) {
                transMonitorInfo.setTxnTime(DateUtil.getCurrentTime());
            }
            /* Step3：累计交易监控信息 */
            long timeStamp = DateUtil.getTimeStamp(DateUtil.getFutureDay(1), "yyyyMMdd");
            int expiryTime = (int) (timeStamp / 1000);
            String statisPreKey = AppParamConstant.MONITOR_STATIS_KEY + DateUtil.getCurrentDate();
            /* Step3.1：法人行交易监控统计信息 */
            String monitorStatisKey = transMonitorInfo.getInstId() + AppParamConstant.MONITOR_ALL + statisPreKey;
            cacheTransMonitorInfo(monitorStatisKey, transMonitorInfo.getTransStatus(), transMonitorInfo.getTxnCost(), expiryTime);
            /* Step3.1.1：法人行渠道交易监控统计信息 */
            monitorStatisKey = transMonitorInfo.getInstId() + AppParamConstant.MONITOR_SRC_CHANNEL + transMonitorInfo.getSrcChannelId() + statisPreKey;
            cacheTransMonitorInfo(monitorStatisKey, transMonitorInfo.getTransStatus(), transMonitorInfo.getTxnCost(), expiryTime);
            /* Step3.1.2：法人行通道交易监控统计信息 */
            for (ChannelMonitorInfo channelMonitorInfo : transMonitorInfo.getChannelMonitorInfoList()) {
                monitorStatisKey = transMonitorInfo.getInstId() + AppParamConstant.MONITOR_DST_CHANNEL + channelMonitorInfo.getChannelId() + statisPreKey;
                cacheTransMonitorInfo(monitorStatisKey, channelMonitorInfo.getTransStatus(), channelMonitorInfo.getChannelTxnCost(), expiryTime);
            }
            /* Step3.1.3：法人行支付产品交易监控统计信息 */
            monitorStatisKey = transMonitorInfo.getInstId() + AppParamConstant.MONITOR_PROD + transMonitorInfo.getBizProdCode() + statisPreKey;
            cacheTransMonitorInfo(monitorStatisKey, transMonitorInfo.getTransStatus(), transMonitorInfo.getTxnCost(), expiryTime);
            /* Step3.2：当存在多个法人行时，也同时登记平台有交易监控统计信息 */
            if (!transMonitorInfo.getInstId().equals(AppParamConstant.DEFAULT_INSTID)) {
                monitorStatisKey = AppParamConstant.IGAS + AppParamConstant.MONITOR_ALL + statisPreKey;
                cacheTransMonitorInfo(monitorStatisKey, transMonitorInfo.getTransStatus(), transMonitorInfo.getTxnCost(), expiryTime);
                /* Step3.2.1：平台渠道交易监控统计信息 */
                monitorStatisKey = AppParamConstant.IGAS + AppParamConstant.MONITOR_SRC_CHANNEL + transMonitorInfo.getSrcChannelId() + statisPreKey;
                cacheTransMonitorInfo(monitorStatisKey, transMonitorInfo.getTransStatus(), transMonitorInfo.getTxnCost(), expiryTime);
                /* Step3.2.2：平台通道交易监控统计信息 */
                for (ChannelMonitorInfo channelMonitorInfo : transMonitorInfo.getChannelMonitorInfoList()) {
                    monitorStatisKey = AppParamConstant.IGAS + AppParamConstant.MONITOR_DST_CHANNEL + channelMonitorInfo.getChannelId() + statisPreKey;
                    cacheTransMonitorInfo(monitorStatisKey, channelMonitorInfo.getTransStatus(), channelMonitorInfo.getChannelTxnCost(), expiryTime);
                }
            }
            /* Step4：获取交易缓存时间 */
            SysParamService sysParamService = new SysParamServiceImpl();
            SysParam sysParam = sysParamService.getSysParamInfo(transMonitorInfo.getInstId().trim(), TRANS_MONITOR_PARAM, MONITOR_EXPIRY_TIMES);
            int cacheMonitorTime = (null == sysParam) ? MONITOR_EXPIRY_SECONDS : Integer.parseInt(sysParam.getParamValue().trim());
            /* Step4：发布交易监控信息 */
            String publishKey = "transMonitor:" + AppParamConstant.DEFAULT_INSTID + DateUtil.getCurrentDate() + DateUtil.getCurrentTime().substring(0, 5);
            List<String> messageList = RedisUtil.getListRange(publishKey, 0, 1);
            if (null != messageList && !messageList.isEmpty()) {
                RedisUtil.onceRightPush(publishKey, JSON.toJSONString(transMonitorInfo));
            } else {
                RedisUtil.onceRightPush(publishKey, JSON.toJSONString(transMonitorInfo));
                RedisUtil.onceExpire(publishKey, cacheMonitorTime);
            }
        } catch (Exception e) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            e.printStackTrace(new PrintWriter(byteArrayOutputStream, true));
            rglog.error("发布交易监控信息到Redis缓存失败:<{}>", byteArrayOutputStream.toString());
        }
    }

    @Override
    public List<TransMonitorInfo> subscribeTransMonitorInfo(MonitorMode monitorMode) throws Exception {
        /* Step1：获取所有缓存的交易监控信息 */
        if (null == monitorMode || null == monitorMode.getInstId() || monitorMode.getInstId().isEmpty()) {
            rglog.error("监控模式参数为空!");
            return null;
        }
        List<TransMonitorInfo> transMonitorInfoList = new ArrayList<>();
        /* Step1.1：获取交易缓存时间 */
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(monitorMode.getInstId().trim(), TRANS_MONITOR_PARAM, MONITOR_EXPIRY_TIMES);
        /* Step1.2：获取监控开始时间 */
        long currentTime = DateUtil.getCurrentTimeStamp();
        int cacheMonitorTime = (null == sysParam) ? MONITOR_EXPIRY_SECONDS : Integer.parseInt(sysParam.getParamValue().trim());
        long monitorTime = currentTime - cacheMonitorTime * 1000L;
        /* Step1.3：根据订单消息的KEY获取Redis缓存的交易信息 */
        List<String> subscribeMessageList = new ArrayList<>();
        String subscribePreKey = "transMonitor:" + AppParamConstant.DEFAULT_INSTID;
        while (monitorTime < currentTime) {
            String subscribeKey = subscribePreKey + DateUtil.getDateByTimeStamp(monitorTime, "yyyyMMddHHmmss").substring(0, 13);
            List<String> monitorMessageList = RedisUtil.getListRange(subscribeKey, 0, -1);
            if (null != monitorMessageList && !monitorMessageList.isEmpty()) {
                subscribeMessageList.addAll(monitorMessageList);
            }
            monitorTime += 10 * 1000;
        }
        /* Step1.4：根据查询条件过滤交易监控信息 */
        if (!subscribeMessageList.isEmpty()) {
            for (String message : subscribeMessageList) {
                TransMonitorInfo transMonitorInfo = JSON.parseObject(message, TransMonitorInfo.class);
                transMonitorInfoList.add(transMonitorInfo);
            }
            /* Step2.1：监控模式是否根据法人行进行监控 */
            if (!transMonitorInfoList.isEmpty() && null != monitorMode.getInstId() && !monitorMode.getInstId().isEmpty() && !monitorMode.getInstId().equals(AppParamConstant.DEFAULT_INSTID)) {
                transMonitorInfoList = transMonitorInfoList.stream().filter(item -> !StringUtil.isEmptyOrNull(item.getInstId()) && item.getInstId().equals(monitorMode.getInstId())).collect(Collectors.toList());
            }
            /* Step2.2：监控模式是否根据交易状态进行监控 */
            if (!transMonitorInfoList.isEmpty() && null != monitorMode.getTransStatus() && !monitorMode.getTransStatus().isEmpty()) {
                transMonitorInfoList = transMonitorInfoList.stream().filter(item -> !StringUtil.isEmptyOrNull(item.getTransStatus()) && item.getTransStatus().equals(monitorMode.getTransStatus())).collect(Collectors.toList());
            }
            /* Step2.3：监控模式是否根据应用服务器进行监控 */
            if (!transMonitorInfoList.isEmpty() && null != monitorMode.getAppSysIp() && !monitorMode.getAppSysIp().isEmpty()) {
                transMonitorInfoList = transMonitorInfoList.stream().filter(item -> !StringUtil.isEmptyOrNull(item.getAppSysIp()) && item.getAppSysIp().equals(monitorMode.getAppSysIp())).collect(Collectors.toList());
            }
            /* Step2.4：监控模式是否根据交易渠道进行监控 */
            if (!transMonitorInfoList.isEmpty() && null != monitorMode.getSrcChannelId() && !monitorMode.getSrcChannelId().isEmpty()) {
                transMonitorInfoList = transMonitorInfoList.stream().filter(item -> !StringUtil.isEmptyOrNull(item.getSrcChannelId()) && item.getSrcChannelId().equals(monitorMode.getSrcChannelId())).collect(Collectors.toList());
            }
            /* Step2.5：监控模式是否根据交易码进行监控 */
            if (!transMonitorInfoList.isEmpty() && null != monitorMode.getTxnNum() && !monitorMode.getTxnNum().isEmpty()) {
                transMonitorInfoList = transMonitorInfoList.stream().filter(item -> !StringUtil.isEmptyOrNull(item.getTxnNum()) && item.getTxnNum().equals(monitorMode.getTxnNum())).collect(Collectors.toList());
            }
            /* Step2.6：监控模式是否根据支付通道进行监控 */
            if (!transMonitorInfoList.isEmpty() && null != monitorMode.getMsgDstId() && !monitorMode.getMsgDstId().isEmpty()) {
                transMonitorInfoList = transMonitorInfoList.stream().filter(item -> (null != item.getChannelMonitorInfoList() && !item.getChannelMonitorInfoList().isEmpty() &&
                        item.getChannelMonitorInfoList().stream().anyMatch(channelInfo -> channelInfo.getChannelId().equals(monitorMode.getMsgDstId())))).collect(Collectors.toList());
            }
        }
        rglog.debug("当前监控模式下共有<{}>笔监控交易信息！", transMonitorInfoList.size());
        /* 按照交易日期及交易时间倒序排序 */
        return transMonitorInfoList.stream().sorted(Comparator.comparing(TransMonitorInfo::getTxnDate).reversed().thenComparing(TransMonitorInfo::getTxnTime).reversed()).collect(Collectors.toList());
    }

    @Override
    public List<MonitorModelInfo> getMonitorModelData(List<SysParam> sysParamList) throws Exception {
        List<MonitorModelInfo> monitorModelInfoList = new ArrayList<>();
        MonitorStatisData monitorStatisData = statisTransMonitorData();
        /* Step1：系统层面成功率推送 */
        if (null != monitorStatisData.getTotalSuccRateMap() && !monitorStatisData.getTotalSuccRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_TOTAL_SUCC_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.TOTAL_SUCC);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getTotalSuccRateMap()));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step2：系统层面失败率推送 */
        if (null != monitorStatisData.getTotalFailRateMap() && !monitorStatisData.getTotalFailRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_TOTAL_FAIL_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.TOTAL_FAIL);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getTotalFailRateMap()));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step3：系统层面超时率推送 */
        if (null != monitorStatisData.getTotalTimeoutRateMap() && !monitorStatisData.getTotalTimeoutRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_TOTAL_TIMEOUT_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.TOTAL_TIMEOUT);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getTotalTimeoutRateMap()));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step4：交易耗时统计推送 */
        if (null != monitorStatisData.getTotalAvgTxnCostMap() && !monitorStatisData.getTotalAvgTxnCostMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_TOTAL_AVG_TXN_COST_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.TOTAL_AVG_TXN_COST);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getTotalAvgTxnCostMap()));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step5：交易渠道成功率推送 */
        if (null != monitorStatisData.getSrcChnlSuccRateMap() && !monitorStatisData.getSrcChnlSuccRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_SRC_CHANNEL_SUCC_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.SRC_CHANNEL_SUCC);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getSrcChnlSuccRateMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step6：交易渠道失败率推送 */
        if (null != monitorStatisData.getSrcChnlFailRateMap() && !monitorStatisData.getSrcChnlFailRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_SRC_CHANNEL_FAIL_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.SRC_CHANNEL_FAIL);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getSrcChnlFailRateMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step7：交易渠道超时率推送 */
        if (null != monitorStatisData.getSrcChnlTimeoutRateMap() && !monitorStatisData.getSrcChnlTimeoutRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_SRC_CHANNEL_TIMEOUT_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.SRC_CHANNEL_TIMEOUT);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getSrcChnlTimeoutRateMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step8：交易渠道交易耗时统计推送 */
        if (null != monitorStatisData.getSrcChnlAvgTxnCostMap() && !monitorStatisData.getSrcChnlAvgTxnCostMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_SRC_CHANNEL_AVG_TXN_COST_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.SRC_CHANNEL_AVG_TXN_COST);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getSrcChnlAvgTxnCostMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step9：支付通道成功率推送 */
        if (null != monitorStatisData.getDstChnlSuccRateMap() && !monitorStatisData.getDstChnlSuccRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_DST_CHANNEL_SUCC_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.DST_CHANNEL_SUCC);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getDstChnlSuccRateMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step10：支付通道失败率推送 */
        if (null != monitorStatisData.getDstChnlFailRateMap() && !monitorStatisData.getDstChnlFailRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_DST_CHANNEL_FAIL_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.DST_CHANNEL_FAIL);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getDstChnlFailRateMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step11：支付通道超时率推送 */
        if (null != monitorStatisData.getDstChnlTimeoutRateMap() && !monitorStatisData.getDstChnlTimeoutRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_DST_CHANNEL_TIMEOUT_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.DST_CHANNEL_TIMEOUT);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getDstChnlTimeoutRateMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step12：支付通道交易耗时统计推送 */
        if (null != monitorStatisData.getDstChnlAvgTxnCostMap() && !monitorStatisData.getDstChnlAvgTxnCostMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_DST_CHANNEL_AVG_TXN_COST_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.DST_CHANNEL_AVG_TXN_COST);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getDstChnlAvgTxnCostMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step13：支付产品成功率推送 */
        if (null != monitorStatisData.getProdSuccRateMap() && !monitorStatisData.getProdSuccRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_PROD_SUCC_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.PROD_SUCC);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getProdSuccRateMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step14：支付产品交易失败率推送 */
        if (null != monitorStatisData.getProdFailRateMap() && !monitorStatisData.getProdFailRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_PROD_FAIL_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.PROD_FAIL);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getProdFailRateMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step15：支付产品交易超时率推送 */
        if (null != monitorStatisData.getProdTimeoutRateMap() && !monitorStatisData.getProdTimeoutRateMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_PROD_TIMEOUT_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.PROD_TIMEOUT);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getProdTimeoutRateMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step16：支付产品交易耗时统计推送 */
        if (null != monitorStatisData.getProdAvgTxnCostMap() && !monitorStatisData.getProdAvgTxnCostMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_PROD_AVG_TXN_COST_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.PROD_AVG_TXN_COST);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getProdAvgTxnCostMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        /* Step17：交易统计相关信息推送 */
        if (null != monitorStatisData.getTransStatisMap() && !monitorStatisData.getTransStatisMap().isEmpty()) {
            Optional<SysParam> sysParamOpt = sysParamList.stream().filter(item -> item.getParamKey().equals(AppParamConstant.MONITOR_TRANS_STATIS_MODEL_ID)).findFirst();
            if (sysParamOpt.isPresent()) {
                MonitorModelInfo monitorModelInfo = new MonitorModelInfo();
                monitorModelInfo.setMonitorModelType(MonitorModelTypeEnum.TRANS_STATIS);
                monitorModelInfo.setMonitorModelId(sysParamOpt.get().getParamValue().trim());
                monitorModelInfo.setMonitorModelData(JSON.toJSONString(monitorStatisData.getTransStatisMap().get(sysParamOpt.get().getInstId())));
                monitorModelInfoList.add(monitorModelInfo);
            }
        }
        return monitorModelInfoList;
    }

    /**
     * 统计交易监控数据
     *
     * @return 交易监控数据
     * @throws Exception 异常
     */
    private MonitorStatisData statisTransMonitorData() throws Exception {
        MonitorStatisData monitorStatisData = null;
        Map<String, String> monitorQuotaMap = RedisUtil.hashGetAll(AppParamConstant.TRANS_MONITOR_CACHE);
        if (null != monitorQuotaMap) {
            monitorStatisData = new MonitorStatisData();
            String currentDate = DateUtil.getCurrentDate();
            for (String quotaKey : monitorQuotaMap.keySet()) {
                if (quotaKey.contains(currentDate)) {
                    String[] arrary = quotaKey.split("_");
                    String instId = arrary[0];
                    MonitorQuota monitorQuota = JSON.parseObject(monitorQuotaMap.get(quotaKey), MonitorQuota.class);
                    if (quotaKey.contains(AppParamConstant.MONITOR_ALL)) {
                        /* 系统级总成功率 */
                        if (null == monitorStatisData.getTotalSuccRateMap()) {
                            Map<String, String> totalSuccRateMap = new HashMap<>();
                            monitorStatisData.setTotalSuccRateMap(totalSuccRateMap);
                        }
                        monitorStatisData.getTotalSuccRateMap().put(instId, monitorQuota.getSuccessRate());
                        /* 系统级总失败率 */
                        if (null == monitorStatisData.getTotalFailRateMap()) {
                            Map<String, String> totalFailRateMap = new HashMap<>();
                            monitorStatisData.setTotalFailRateMap(totalFailRateMap);
                        }
                        monitorStatisData.getTotalFailRateMap().put(instId, monitorQuota.getFailRate());
                        /* 系统级总超时率 */
                        if (null == monitorStatisData.getTotalTimeoutRateMap()) {
                            Map<String, String> totalTimeoutRateMap = new HashMap<>();
                            monitorStatisData.setTotalTimeoutRateMap(totalTimeoutRateMap);
                        }
                        monitorStatisData.getTotalTimeoutRateMap().put(instId, monitorQuota.getTimeoutRate());
                        /* 系统级总平均耗时率 */
                        if (null == monitorStatisData.getTotalAvgTxnCostMap()) {
                            Map<String, String> totalAvgTxnCostRateMap = new HashMap<>();
                            monitorStatisData.setTotalAvgTxnCostMap(totalAvgTxnCostRateMap);
                        }
                        monitorStatisData.getTotalAvgTxnCostMap().put(instId, String.valueOf(monitorQuota.getAvgTxnCost()));
                    } else if (quotaKey.contains(AppParamConstant.MONITOR_SRC_CHANNEL)) {
                        String srcChannelId = arrary[2];
                        /* 渠道交易成功率 */
                        if (null == monitorStatisData.getSrcChnlSuccRateMap()) {
                            Map<String, Map<String, String>> srcChnlSuccRateMap = new HashMap<>();
                            monitorStatisData.setSrcChnlSuccRateMap(srcChnlSuccRateMap);
                        }
                        Map<String, String> succMap = monitorStatisData.getSrcChnlSuccRateMap().get(instId);
                        succMap = null == succMap ? (new HashMap<>()) : succMap;
                        succMap.put(srcChannelId, monitorQuota.getSuccessRate());
                        monitorStatisData.getSrcChnlSuccRateMap().put(instId, succMap);
                        /* 渠道交易失败率 */
                        if (null == monitorStatisData.getSrcChnlFailRateMap()) {
                            Map<String, Map<String, String>> srcChnlFailRateMap = new HashMap<>();
                            monitorStatisData.setSrcChnlFailRateMap(srcChnlFailRateMap);
                        }
                        Map<String, String> failMap = monitorStatisData.getSrcChnlFailRateMap().get(instId);
                        failMap = null == failMap ? (new HashMap<>()) : failMap;
                        failMap.put(srcChannelId, monitorQuota.getFailRate());
                        monitorStatisData.getSrcChnlFailRateMap().put(instId, failMap);
                        /* 渠道交易超时率 */
                        if (null == monitorStatisData.getSrcChnlTimeoutRateMap()) {
                            Map<String, Map<String, String>> srcChnlTimeoutRateMap = new HashMap<>();
                            monitorStatisData.setSrcChnlTimeoutRateMap(srcChnlTimeoutRateMap);
                        }
                        Map<String, String> timeoutMap = monitorStatisData.getSrcChnlTimeoutRateMap().get(instId);
                        timeoutMap = null == timeoutMap ? (new HashMap<>()) : timeoutMap;
                        timeoutMap.put(srcChannelId, monitorQuota.getTimeoutRate());
                        monitorStatisData.getSrcChnlTimeoutRateMap().put(instId, timeoutMap);
                        /* 渠道交易平均耗时 */
                        if (null == monitorStatisData.getSrcChnlAvgTxnCostMap()) {
                            Map<String, Map<String, String>> srcChnlAvgTxnCostRateMap = new HashMap<>();
                            monitorStatisData.setSrcChnlAvgTxnCostMap(srcChnlAvgTxnCostRateMap);
                        }
                        Map<String, String> avgTxnCodeMap = monitorStatisData.getSrcChnlAvgTxnCostMap().get(instId);
                        avgTxnCodeMap = null == avgTxnCodeMap ? (new HashMap<>()) : avgTxnCodeMap;
                        avgTxnCodeMap.put(srcChannelId, String.valueOf(monitorQuota.getAvgTxnCost()));
                        monitorStatisData.getSrcChnlAvgTxnCostMap().put(instId, avgTxnCodeMap);
                    } else if (quotaKey.contains(AppParamConstant.MONITOR_DST_CHANNEL)) {
                        String dstChannelId = arrary[2];
                        /* 通道交易成功率 */
                        if (null == monitorStatisData.getDstChnlSuccRateMap()) {
                            Map<String, Map<String, String>> dstChnlSuccRateMap = new HashMap<>();
                            monitorStatisData.setDstChnlSuccRateMap(dstChnlSuccRateMap);
                        }
                        Map<String, String> succMap = monitorStatisData.getDstChnlSuccRateMap().get(instId);
                        succMap = null == succMap ? (new HashMap<>()) : succMap;
                        succMap.put(dstChannelId, monitorQuota.getSuccessRate());
                        monitorStatisData.getDstChnlSuccRateMap().put(instId, succMap);
                        /* 通道交易失败率 */
                        if (null == monitorStatisData.getDstChnlFailRateMap()) {
                            Map<String, Map<String, String>> dstChnlFailRateMap = new HashMap<>();
                            monitorStatisData.setDstChnlFailRateMap(dstChnlFailRateMap);
                        }
                        Map<String, String> failMap = monitorStatisData.getDstChnlFailRateMap().get(instId);
                        failMap = null == failMap ? (new HashMap<>()) : failMap;
                        failMap.put(dstChannelId, monitorQuota.getFailRate());
                        monitorStatisData.getDstChnlFailRateMap().put(instId, failMap);
                        /* 通道交易超时率 */
                        if (null == monitorStatisData.getDstChnlTimeoutRateMap()) {
                            Map<String, Map<String, String>> dstChnlTimeoutRateMap = new HashMap<>();
                            monitorStatisData.setDstChnlTimeoutRateMap(dstChnlTimeoutRateMap);
                        }
                        Map<String, String> timeoutMap = monitorStatisData.getDstChnlTimeoutRateMap().get(instId);
                        timeoutMap = null == timeoutMap ? (new HashMap<>()) : timeoutMap;
                        timeoutMap.put(dstChannelId, monitorQuota.getTimeoutRate());
                        monitorStatisData.getDstChnlTimeoutRateMap().put(instId, timeoutMap);
                        /* 通道交易平均耗时 */
                        if (null == monitorStatisData.getDstChnlAvgTxnCostMap()) {
                            Map<String, Map<String, String>> dstChnlAvgTxnCostRateMap = new HashMap<>();
                            monitorStatisData.setDstChnlAvgTxnCostMap(dstChnlAvgTxnCostRateMap);
                        }
                        Map<String, String> avgTxnCodeMap = monitorStatisData.getDstChnlAvgTxnCostMap().get(instId);
                        avgTxnCodeMap = null == avgTxnCodeMap ? (new HashMap<>()) : avgTxnCodeMap;
                        avgTxnCodeMap.put(dstChannelId, String.valueOf(monitorQuota.getAvgTxnCost()));
                        monitorStatisData.getDstChnlAvgTxnCostMap().put(instId, avgTxnCodeMap);
                    } else if (quotaKey.contains(AppParamConstant.MONITOR_PROD)) {
                        String bizProdCode = arrary[2];
                        /* 支付产品交易成功率 */
                        if (null == monitorStatisData.getProdSuccRateMap()) {
                            Map<String, Map<String, String>> prodSuccRateMap = new HashMap<>();
                            monitorStatisData.setProdSuccRateMap(prodSuccRateMap);
                        }
                        Map<String, String> succMap = monitorStatisData.getProdSuccRateMap().get(instId);
                        succMap = null == succMap ? (new HashMap<>()) : succMap;
                        succMap.put(bizProdCode, monitorQuota.getSuccessRate());
                        monitorStatisData.getProdSuccRateMap().put(instId, succMap);
                        /* 支付产品交易失败率 */
                        if (null == monitorStatisData.getProdFailRateMap()) {
                            Map<String, Map<String, String>> prodFailRateMap = new HashMap<>();
                            monitorStatisData.setProdFailRateMap(prodFailRateMap);
                        }
                        Map<String, String> failMap = monitorStatisData.getProdFailRateMap().get(instId);
                        failMap = null == failMap ? (new HashMap<>()) : failMap;
                        failMap.put(bizProdCode, monitorQuota.getFailRate());
                        monitorStatisData.getProdFailRateMap().put(instId, failMap);
                        /* 支付产品交易超时率 */
                        if (null == monitorStatisData.getProdTimeoutRateMap()) {
                            Map<String, Map<String, String>> prodTimeoutRateMap = new HashMap<>();
                            monitorStatisData.setProdTimeoutRateMap(prodTimeoutRateMap);
                        }
                        Map<String, String> timeoutMap = monitorStatisData.getProdTimeoutRateMap().get(instId);
                        timeoutMap = null == timeoutMap ? (new HashMap<>()) : timeoutMap;
                        timeoutMap.put(bizProdCode, monitorQuota.getTimeoutRate());
                        monitorStatisData.getProdTimeoutRateMap().put(instId, timeoutMap);
                        /* 支付产品交易平均耗时 */
                        if (null == monitorStatisData.getProdAvgTxnCostMap()) {
                            Map<String, Map<String, String>> prodAvgTxnCostRateMap = new HashMap<>();
                            monitorStatisData.setProdAvgTxnCostMap(prodAvgTxnCostRateMap);
                        }
                        Map<String, String> avgTxnCodeMap = monitorStatisData.getProdAvgTxnCostMap().get(instId);
                        avgTxnCodeMap = null == avgTxnCodeMap ? (new HashMap<>()) : avgTxnCodeMap;
                        avgTxnCodeMap.put(bizProdCode, String.valueOf(monitorQuota.getAvgTxnCost()));
                        monitorStatisData.getProdAvgTxnCostMap().put(instId, avgTxnCodeMap);
                    }
                    /* 交易统计模型 */
                    if (null == monitorStatisData.getTransStatisMap()) {
                        Map<String, Map<String, String>> transStatisMap = new HashMap<>();
                        monitorStatisData.setTransStatisMap(transStatisMap);
                    }
                    Map<String, String> statisMap = monitorStatisData.getTransStatisMap().get(instId);
                    statisMap = null == statisMap ? (new HashMap<>()) : statisMap;
                    statisMap.put("totalNum", String.valueOf(monitorQuota.getTotalNum()));
                    statisMap.put("totalSuccessNum", String.valueOf(monitorQuota.getTotalSuccessNum()));
                    statisMap.put("totalFailNum", String.valueOf(monitorQuota.getTotalFailNum()));
                    statisMap.put("totalTimeoutNum", String.valueOf(monitorQuota.getTotalTimeoutNum()));
                    statisMap.put("seriesFailNum", String.valueOf(monitorQuota.getSeriesFailNum()));
                    statisMap.put("seriesTimeoutNum", String.valueOf(monitorQuota.getSeriesTimeoutNum()));
                    monitorStatisData.getTransStatisMap().put(instId, statisMap);
                }
            }
        } else {
            rglog.info("当前Redis中没有交易监控统计数据!");
        }
        return monitorStatisData;
    }

    /**
     * 交易监控信息统计
     *
     * @param quotaKey    redis缓存KEY
     * @param transStatus 交易状态
     * @param transCost   交易耗时
     * @param expiryTime  统计数据过期时间
     * @throws Exception 异常
     */
    private void cacheTransMonitorInfo(String quotaKey, String transStatus, int transCost, int expiryTime) throws Exception {
        MonitorQuota monitorQuota = new MonitorQuota();
        String monitorQuotaString = RedisUtil.hashGet(AppParamConstant.TRANS_MONITOR_CACHE, quotaKey);
        if (!StringUtil.isEmptyOrNull(monitorQuotaString)) {
            monitorQuota = JSON.parseObject(monitorQuotaString, MonitorQuota.class);
            monitorQuota.setAvgTxnCost((monitorQuota.getAvgTxnCost() + transCost) / 2);
        } else {
            monitorQuota.setTotalNum(0);
            monitorQuota.setTotalSuccessNum(0);
            monitorQuota.setTotalFailNum(0);
            monitorQuota.setTotalTimeoutNum(0);
            monitorQuota.setSeriesFailNum(0);
            monitorQuota.setSeriesTimeoutNum(0);
            monitorQuota.setAvgTxnCost(transCost);
            monitorQuota.setSuccessRate("100.00");
            monitorQuota.setFailRate("0.00");
            monitorQuota.setTimeoutRate("0.00");
        }
        monitorQuota.setTotalNum(monitorQuota.getTotalNum() + 1);
        if (TransStatusEnum.TRANS_SUCC.getStatus().equals(transStatus)) {
            monitorQuota.setTotalSuccessNum(monitorQuota.getTotalSuccessNum() + 1);
            monitorQuota.setSeriesFailNum(0);
            monitorQuota.setSeriesTimeoutNum(0);
        } else if (TransStatusEnum.SYSTEM_REJECT.getStatus().equals(transStatus)) {
            monitorQuota.setTotalFailNum(monitorQuota.getTotalFailNum() + 1);
            monitorQuota.setSeriesTimeoutNum(0);
            monitorQuota.setSeriesFailNum(monitorQuota.getSeriesFailNum() + 1);
        } else if (TransStatusEnum.TRANS_TIMEOUT.getStatus().equals(transStatus)) {
            monitorQuota.setTotalTimeoutNum(monitorQuota.getTotalTimeoutNum() + 1);
            monitorQuota.setSeriesFailNum(0);
            monitorQuota.setSeriesTimeoutNum(monitorQuota.getSeriesTimeoutNum() + 1);
        } else {
            rglog.warn("未知的交易状态:{}", transStatus);
        }
        /* 计算交易成功率、失败率及超时率，设置精确到小数点后2位 */
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);
        String result = numberFormat.format((float) monitorQuota.getTotalSuccessNum() / (float) monitorQuota.getTotalNum() * 100);
        monitorQuota.setSuccessRate(result);
        result = numberFormat.format((float) monitorQuota.getTotalFailNum() / (float) monitorQuota.getTotalNum() * 100);
        monitorQuota.setFailRate(result);
        result = numberFormat.format((float) monitorQuota.getTotalTimeoutNum() / (float) monitorQuota.getTotalNum() * 100);
        monitorQuota.setTimeoutRate(result);
        RedisUtil.hashSet(AppParamConstant.TRANS_MONITOR_CACHE, quotaKey, JSON.toJSONString(monitorQuota), expiryTime);
    }
}
